package cn.signalpha.modules.pay.granter;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.json.JSONUtil;
import cn.signalpha.common.cache.ConfigCache;
import cn.signalpha.common.cache.ConfigKeys;
import cn.signalpha.common.dto.ConfigDTO;
import cn.signalpha.core.log.exception.ServiceException;
import cn.signalpha.core.tool.jackson.JsonUtil;
import cn.signalpha.core.tool.support.Kv;
import cn.signalpha.core.tool.utils.CollectionUtil;
import cn.signalpha.core.tool.utils.ObjectUtil;
import cn.signalpha.core.tool.utils.StringPool;
import cn.signalpha.core.tool.utils.StringUtil;
import cn.signalpha.modules.com.entity.UserOauth;
import cn.signalpha.modules.com.entity.enums.UserSourceEnum;
import cn.signalpha.modules.com.service.UserOauthService;
import cn.signalpha.modules.pay.dto.PayDTO;
import cn.signalpha.modules.pay.dto.RefundDTO;
import cn.signalpha.modules.pay.dto.SettleOrderDTO;
import cn.signalpha.modules.pay.dto.SettleUserDTO;
import cn.signalpha.modules.pay.enums.PayClientEnum;
import cn.signalpha.modules.pay.provider.IPayGranter;
import cn.signalpha.modules.pay.vo.RefundVO;
import cn.signalpha.modules.pay.vo.SettleOrderVO;
import cn.signalpha.modules.pay.vo.SettleUserVO;
import cn.signalpha.modules.shop.service.SellerService;
import com.ijpay.core.IJPayHttpResponse;
import com.ijpay.core.enums.AuthTypeEnum;
import com.ijpay.core.enums.RequestMethodEnum;
import com.ijpay.core.kit.PayKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.enums.WxDomainEnum;
import com.ijpay.wxpay.enums.v3.BasePayApiEnum;
import com.ijpay.wxpay.enums.v3.ProfitSharingApiEnum;
import com.ijpay.wxpay.model.ReceiverModel;
import com.ijpay.wxpay.model.v3.*;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.*;

/**
 * 微信支付
 *
 * @author signalpha
 */
@Slf4j
@Component
@AllArgsConstructor
public class WxPayV3Granter implements IPayGranter {

	private final WxMpService wxMpService;
	private final WxMaService wxMaService;
	private final SellerService sellerService;
	private final UserOauthService userOauthService;

	@Override
	public String getPayVO(PayDTO payDTO) {
		ConfigDTO.WxPayDTO config = ConfigCache.getObject(ConfigKeys.WX_PAY, ConfigDTO.WxPayDTO.class);
		payDTO.setNotifyUrl(config.getDomain().concat(payDTO.getNotifyUrl()).concat("/wx/v3"));
		switch (Objects.requireNonNull(PayClientEnum.instance(payDTO.getPayClient()), "支付终端错误")){
			case H5:
				return wxH5Pay(payDTO);
			case APP:
				return wxAppPay(payDTO);
			case PUBLIC:
				return wxPublicPay(payDTO);
			case MINI_APP:
				return wxMiniAppPay(payDTO);
			default:
				throw new ServiceException("终端未实现");
		}
	}

	@Override
	public String verifyNotify(Map<String, String> params) {
		String timestamp = MapUtil.getStr(params, "timestamp");
		String nonce = MapUtil.getStr(params, "nonce");
		String serialNo = MapUtil.getStr(params, "serialNo");
		String signature = MapUtil.getStr(params, "signature");
		String result = MapUtil.getStr(params, "result");
		WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
		byte[] platformCertByte = Base64.getDecoder().decode(wxPayApiConfig.getPlatformCertPath());
		InputStream platformCert = new ByteArrayInputStream(platformCertByte);
		String plainText = null;
		try {
			plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp,
				wxPayApiConfig.getApiKey3(), platformCert);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return plainText;
	}

	/**
	 * 微信H5 支付
	 */
	@SneakyThrows
	private String wxH5Pay(PayDTO payDTO) {
		if(StringUtil.isBlank(payDTO.getAppId())) {
			throw new ServiceException("appId不能为空");
		}

		int totalFee = new BigDecimal(payDTO.getPayMoney()).movePointRight(2).intValue();
		WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
		UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
			.setAppid(payDTO.getAppId())
			.setMchid(wxPayApiConfig.getMchId())
			.setDescription(payDTO.getBody())
			.setOut_trade_no(payDTO.getPayNo())
			.setAttach(payDTO.getNotifyParams())
			.setNotify_url(payDTO.getNotifyUrl())
			.setAmount(new Amount().setTotal(totalFee))
			.setScene_info(
				new SceneInfo()
					.setPayer_client_ip(payDTO.getIp()).
					setH5_info(new H5Info()
						.setType("Wap")))
			.setSettle_info(new SettleInfo().setProfit_sharing(payDTO.getIsSharing() == 1));

		if(StringUtil.isBlank(wxPayApiConfig.getKeyPath())){
			throw new ServiceException("未设置key.pem证书");
		}
		byte[] keyByte = Base64.getDecoder().decode(wxPayApiConfig.getKeyPath());
		InputStream keyInputStream = new ByteArrayInputStream(keyByte);
		PrivateKey privateKey = PayKit.getPrivateKeyByKeyContent(IoUtil.read(keyInputStream, StandardCharsets.UTF_8), AuthTypeEnum.RSA.getCode());
		IJPayHttpResponse response = WxPayApi.v3(
			RequestMethodEnum.POST,
			WxDomainEnum.CHINA.toString(),
			BasePayApiEnum.H5_PAY.toString(),
			wxPayApiConfig.getMchId(),
			String.valueOf(wxPayApiConfig.getExParams()),
			null,
			privateKey,
			JSONUtil.toJsonStr(unifiedOrderModel)
		);
		if(response.getStatus() != 200){
			Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
			throw new ServiceException(StringUtil.format("拉起支付失败[{}]", responseMap.get("message")));
		}
		byte[] platformCertByte = Base64.getDecoder().decode(wxPayApiConfig.getPlatformCertPath());
		InputStream platformCert = new ByteArrayInputStream(platformCertByte);
		boolean verifySignature = WxPayKit.verifySignature(response, platformCert);
		if(!verifySignature){
			throw new ServiceException("支付验签失败，请检查平台证书是否正确");
		}
		Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
		String webUrl = String.valueOf(responseMap.get("mweb_url"));
		return StringUtil.builder(webUrl, "&redirect_url=", URLUtil.encode(payDTO.getReturnUrl())).toString();
	}

	/**
	 * 微信公众号 支付
	 */
	@SneakyThrows
	private String wxPublicPay(PayDTO payDTO) {
//		if(StringUtil.isAnyBlank(payDTO.getCode(), payDTO.getAppId())) {
//			throw new ServiceException("appId或code不能为空");
//		}
//		String openId;
//		WxOAuth2Service oAuth2Service = wxMpService.switchoverTo(payDTO.getAppId()).getOAuth2Service();
//		try {
//			openId = oAuth2Service.getAccessToken(payDTO.getCode()).getOpenId();
//		} catch (WxErrorException e) {
//			throw new ServiceException(e.getError().getErrorMsg());
//		}
		ConfigDTO.WxMpDTO config = ConfigCache.getObject(ConfigKeys.WX_MP, ConfigDTO.WxMpDTO.class);
		UserOauth userOauth = userOauthService.getByUserIdAndSourceAndAppId(payDTO.getUserId(), UserSourceEnum.WECHAT_PUBLIC.getValue(), config.getAppId());
		if(ObjectUtil.isEmpty(userOauth)){
			throw new ServiceException("未获取到用户授权信息openId");
		}

		int totalFee = new BigDecimal(payDTO.getPayMoney()).movePointRight(2).intValue();
		WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
		UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
			.setAppid(config.getAppId())
			.setMchid(wxPayApiConfig.getMchId())
			.setDescription(payDTO.getBody())
			.setOut_trade_no(payDTO.getPayNo())
			.setAttach(payDTO.getNotifyParams())
			.setNotify_url(payDTO.getNotifyUrl())
			.setAmount(new Amount().setTotal(totalFee))
			.setPayer(new Payer().setOpenid(userOauth.getOpenId()))
			.setSettle_info(new SettleInfo().setProfit_sharing(payDTO.getIsSharing() == 1));

		if(StringUtil.isBlank(wxPayApiConfig.getKeyPath())){
			throw new ServiceException("未设置key.pem证书");
		}
		byte[] keyByte = Base64.getDecoder().decode(wxPayApiConfig.getKeyPath());
		InputStream keyInputStream = new ByteArrayInputStream(keyByte);
		PrivateKey privateKey = PayKit.getPrivateKeyByKeyContent(IoUtil.read(keyInputStream, StandardCharsets.UTF_8), AuthTypeEnum.RSA.getCode());
		IJPayHttpResponse response = WxPayApi.v3(
			RequestMethodEnum.POST,
			WxDomainEnum.CHINA.toString(),
			BasePayApiEnum.JS_API_PAY.toString(),
			wxPayApiConfig.getMchId(),
			String.valueOf(wxPayApiConfig.getExParams()),
			null,
			privateKey,
			JSONUtil.toJsonStr(unifiedOrderModel)
		);
		if(response.getStatus() != 200){
			Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
			throw new ServiceException(StringUtil.format("拉起支付失败[{}]", responseMap.get("message")));
		}

		byte[] platformCertByte = Base64.getDecoder().decode(wxPayApiConfig.getPlatformCertPath());
		InputStream platformCert = new ByteArrayInputStream(platformCertByte);
		boolean verifySignature = WxPayKit.verifySignature(response, platformCert);
		if(!verifySignature){
			throw new ServiceException("支付验签失败，请检查平台证书是否正确");
		}
		Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
		String prepayId = String.valueOf(responseMap.get("prepay_id"));
		return JsonUtil.toJson(WxPayKit.jsApiCreateSign(config.getAppId(), prepayId, privateKey));
	}

	/**
	 * 微信小程序 支付
	 */
	@SneakyThrows
	private String wxMiniAppPay(PayDTO payDTO) {
//		if(StringUtil.isAnyBlank(payDTO.getCode(), payDTO.getAppId())) {
//			throw new ServiceException("appId或code不能为空");
//		}
//		String openId;
//		try {
//			openId = wxMaService.getUserService().getSessionInfo(payDTO.getCode()).getOpenid();
//		} catch (WxErrorException e) {
//			throw new ServiceException(e.getError().getErrorMsg());
//		}
		ConfigDTO.WxMaDTO config = ConfigCache.getObject(ConfigKeys.WX_MA, ConfigDTO.WxMaDTO.class);
		UserOauth userOauth = userOauthService.getByUserIdAndSourceAndAppId(payDTO.getUserId(), UserSourceEnum.WECHAT_MINI_APP.getValue(), config.getAppId());
		if(ObjectUtil.isEmpty(userOauth)){
			throw new ServiceException("未获取到用户授权信息openId");
		}

		int totalFee = new BigDecimal(payDTO.getPayMoney()).movePointRight(2).intValue();
		WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
		UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
			.setAppid(config.getAppId())
			.setMchid(wxPayApiConfig.getMchId())
			.setDescription(payDTO.getBody())
			.setOut_trade_no(payDTO.getPayNo())
			.setAttach(payDTO.getNotifyParams())
			.setNotify_url(payDTO.getNotifyUrl())
			.setAmount(new Amount().setTotal(totalFee))
			.setPayer(new Payer().setOpenid(userOauth.getOpenId()))
			.setSettle_info(new SettleInfo().setProfit_sharing(payDTO.getIsSharing() == 1));

		if(StringUtil.isBlank(wxPayApiConfig.getKeyPath())){
			throw new ServiceException("未设置key.pem证书");
		}
		byte[] keyByte = Base64.getDecoder().decode(wxPayApiConfig.getKeyPath());
		InputStream keyInputStream = new ByteArrayInputStream(keyByte);
		PrivateKey privateKey = PayKit.getPrivateKeyByKeyContent(IoUtil.read(keyInputStream, StandardCharsets.UTF_8), AuthTypeEnum.RSA.getCode());
		IJPayHttpResponse response = WxPayApi.v3(
			RequestMethodEnum.POST,
			WxDomainEnum.CHINA.toString(),
			BasePayApiEnum.JS_API_PAY.toString(),
			wxPayApiConfig.getMchId(),
			String.valueOf(wxPayApiConfig.getExParams()),
			null,
			privateKey,
			JSONUtil.toJsonStr(unifiedOrderModel)
		);
		if(response.getStatus() != 200){
			Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
			throw new ServiceException(StringUtil.format("拉起支付失败[{}]", responseMap.get("message")));
		}

		byte[] platformCertByte = Base64.getDecoder().decode(wxPayApiConfig.getPlatformCertPath());
		InputStream platformCert = new ByteArrayInputStream(platformCertByte);
		boolean verifySignature = WxPayKit.verifySignature(response, platformCert);
		if(!verifySignature){
			throw new ServiceException("支付验签失败，请检查平台证书是否正确");
		}
		Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
		String prepayId = String.valueOf(responseMap.get("prepay_id"));
		return JsonUtil.toJson(WxPayKit.jsApiCreateSign(config.getAppId(), prepayId, privateKey));
	}

	/**
	 * 微信APP 支付
	 */
	@SneakyThrows
	private String wxAppPay(PayDTO payDTO) {
		if(StringUtil.isBlank(payDTO.getAppId())) {
			throw new ServiceException("appId不能为空");
		}

		int totalFee = new BigDecimal(payDTO.getPayMoney()).movePointRight(2).intValue();
		WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
		UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
			.setAppid(payDTO.getAppId())
			.setMchid(wxPayApiConfig.getMchId())
			.setDescription(payDTO.getBody())
			.setOut_trade_no(payDTO.getPayNo())
			.setAttach(payDTO.getNotifyParams())
			.setNotify_url(payDTO.getNotifyUrl())
			.setAmount(new Amount().setTotal(totalFee))
			.setSettle_info(new SettleInfo().setProfit_sharing(payDTO.getIsSharing() == 1));

		if(StringUtil.isBlank(wxPayApiConfig.getKeyPath())){
			throw new ServiceException("未设置key.pem证书");
		}
		byte[] keyByte = Base64.getDecoder().decode(wxPayApiConfig.getKeyPath());
		InputStream keyInputStream = new ByteArrayInputStream(keyByte);
		PrivateKey privateKey = PayKit.getPrivateKeyByKeyContent(IoUtil.read(keyInputStream, StandardCharsets.UTF_8), AuthTypeEnum.RSA.getCode());
		IJPayHttpResponse response = WxPayApi.v3(
			RequestMethodEnum.POST,
			WxDomainEnum.CHINA.toString(),
			BasePayApiEnum.APP_PAY.toString(),
			wxPayApiConfig.getMchId(),
			String.valueOf(wxPayApiConfig.getExParams()),
			null,
			privateKey,
			JSONUtil.toJsonStr(unifiedOrderModel)
		);
		if(response.getStatus() != 200){
			Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
			throw new ServiceException(StringUtil.format("拉起支付失败[{}]", responseMap.get("message")));
		}

		byte[] platformCertByte = Base64.getDecoder().decode(wxPayApiConfig.getPlatformCertPath());
		InputStream platformCert = new ByteArrayInputStream(platformCertByte);
		boolean verifySignature = WxPayKit.verifySignature(response, platformCert);
		if(!verifySignature){
			throw new ServiceException("支付验签失败，请检查平台证书是否正确");
		}
		Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
		String prepayId = String.valueOf(responseMap.get("prepay_id"));
		return JsonUtil.toJson(WxPayKit.appCreateSign(payDTO.getAppId(), wxPayApiConfig.getMchId(), prepayId, privateKey));
	}

	@Override
	@SneakyThrows
	public RefundVO refund(RefundDTO refundDTO) {
		ConfigDTO.WxPayDTO config = ConfigCache.getObject(ConfigKeys.WX_PAY, ConfigDTO.WxPayDTO.class);
		refundDTO.setNotifyUrl(config.getDomain().concat(refundDTO.getNotifyUrl()).concat("/wx/v3"));
		int totalFee = BigDecimal.valueOf(refundDTO.getTotalMoney()).movePointRight(2).intValue();
		int refundFee = BigDecimal.valueOf(refundDTO.getRefundMoney()).movePointRight(2).intValue();
		List<RefundGoodsDetail> list = new ArrayList<>();
		RefundGoodsDetail refundGoodsDetail = new RefundGoodsDetail()
			.setMerchant_goods_id(refundDTO.getParams().getStr("goodsId"))
			.setGoods_name(refundDTO.getParams().getStr("goodsName"))
			.setUnit_price(BigDecimal.valueOf(refundDTO.getParams().getDouble("goodsUnitPrice")).movePointRight(2).intValue())
			.setRefund_amount(refundFee)
			.setRefund_quantity(refundDTO.getParams().getInt("goodsNum"));
		list.add(refundGoodsDetail);

		RefundModel refundModel = new RefundModel()
			.setTransaction_id(refundDTO.getPayBizNo())
			.setOut_trade_no(refundDTO.getPayNo())
			.setOut_refund_no(refundDTO.getRefundNo())
			.setReason("退款")
			.setNotify_url(refundDTO.getNotifyUrl())
			.setAmount(new RefundAmount().setRefund(refundFee).setTotal(totalFee).setCurrency("CNY"))
			.setGoods_detail(list);

		WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
		if(StringUtil.isBlank(wxPayApiConfig.getKeyPath())){
			throw new ServiceException("未设置key.pem证书");
		}
		byte[] keyByte = Base64.getDecoder().decode(wxPayApiConfig.getKeyPath());
		InputStream keyInputStream = new ByteArrayInputStream(keyByte);
		PrivateKey privateKey = PayKit.getPrivateKeyByKeyContent(IoUtil.read(keyInputStream, StandardCharsets.UTF_8), AuthTypeEnum.RSA.getCode());
		IJPayHttpResponse response = WxPayApi.v3(
			RequestMethodEnum.POST,
			WxDomainEnum.CHINA.toString(),
			BasePayApiEnum.REFUND.toString(),
			wxPayApiConfig.getMchId(),
			String.valueOf(wxPayApiConfig.getExParams()),
			null,
			privateKey,
			JSONUtil.toJsonStr(refundModel)
		);
		if(response.getStatus() != 200){
			Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
			throw new ServiceException(StringUtil.format("发起退款失败[{}]", responseMap.get("message")));
		}

		byte[] platformCertByte = Base64.getDecoder().decode(wxPayApiConfig.getPlatformCertPath());
		InputStream platformCert = new ByteArrayInputStream(platformCertByte);
		boolean verifySignature = WxPayKit.verifySignature(response, platformCert);
		if(!verifySignature){
			throw new ServiceException("退款验签失败，请检查平台证书是否正确");
		}
		Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
		return RefundVO.builder().code(StringPool.YES).orderBizNo(String.valueOf(responseMap.get("refund_id"))).build();
	}

	@Override
	@SneakyThrows
	public SettleUserVO settleUser(SettleUserDTO settleUserDTO) {
		Long userId = settleUserDTO.getTargetId();
		if(settleUserDTO.getType() == 1){
			userId = sellerService.getById(settleUserDTO.getTargetId()).getUserId();
		}
		List<Kv> userList = new ArrayList<>();
		userOauthService.listByUserId(userId).forEach(userOauth -> {
			if(StringUtil.isNoneBlank(userOauth.getAppId(), userOauth.getOpenId())){
				userList.add(Kv.create().set("appId", userOauth.getAppId()).set("openId", userOauth.getOpenId()));
			}
		});
		if(CollectionUtil.isEmpty(userList)){
			String msg = StringUtil.format(
				"添加分账接收方失败：未查询到分账方openId，类型[{}]，目标id[{}]",
				settleUserDTO.getType() == 1 ? "个人" : "商户",
				settleUserDTO.getTargetId());
			return SettleUserVO.builder().code(StringPool.NO).msg(msg).build();
		}

		for(Kv kv : userList){
			AddReceivers receiver = AddReceivers.builder()
				.appid(kv.getStr("appId"))
				.type("PERSONAL_OPENID")
				.account(kv.getStr("openId"))
				.relation_type(settleUserDTO.getRelationType())
				.build();
			WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
			if(StringUtil.isBlank(wxPayApiConfig.getKeyPath())){
				return SettleUserVO.builder().code(StringPool.NO).msg("未设置key.pem证书").build();
			}
			byte[] keyByte = Base64.getDecoder().decode(wxPayApiConfig.getKeyPath());
			InputStream keyInputStream = new ByteArrayInputStream(keyByte);
			PrivateKey privateKey = PayKit.getPrivateKeyByKeyContent(IoUtil.read(keyInputStream, StandardCharsets.UTF_8), AuthTypeEnum.RSA.getCode());
			IJPayHttpResponse response = WxPayApi.v3(
				RequestMethodEnum.POST,
				WxDomainEnum.CHINA.toString(),
				ProfitSharingApiEnum.PROFIT_SHARING_RECEIVERS_ADD.toString(),
				wxPayApiConfig.getMchId(),
				String.valueOf(wxPayApiConfig.getExParams()),
				null,
				privateKey,
				JSONUtil.toJsonStr(receiver)
			);
			if(response.getStatus() != 200){
				Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
				return SettleUserVO.builder().code(StringPool.NO).msg(MapUtil.getStr(responseMap, "message")).build();
			}

			byte[] platformCertByte = Base64.getDecoder().decode(wxPayApiConfig.getPlatformCertPath());
			InputStream platformCert = new ByteArrayInputStream(platformCertByte);
			boolean verifySignature = WxPayKit.verifySignature(response, platformCert);
			if(!verifySignature){
				return SettleUserVO.builder().code(StringPool.NO).msg("添加分账人验签失败，请检查平台证书是否正确").build();
			}
		}
		return SettleUserVO.builder().code(StringPool.YES).msg(StringPool.EMPTY).build();
	}

	@Override
	@SneakyThrows
	public SettleOrderVO settleOrder(SettleOrderDTO settleOrderDTO) {
		int amount = BigDecimal.valueOf(settleOrderDTO.getAmount()).movePointRight(2).intValue();
		if(amount <= 0){
			return SettleOrderVO.builder().code(StringPool.YES).msg("小于0元无需分账").build();
		}

		Long userId = settleOrderDTO.getTargetId();
		if(settleOrderDTO.getType() == 1){
			userId = sellerService.getById(settleOrderDTO.getTargetId()).getUserId();
		}

		List<ReceiverModel> receiverModelList = new ArrayList<>();
		List<UserOauth> userOauthList = userOauthService.listByUserId(userId);
		receiverModelList.add(ReceiverModel.builder()
			.type("PERSONAL_OPENID")
			.account(userOauthList.get(0).getOpenId())
			.amount(amount)
			.description("平台入账")
			.build());

		WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
		ProfitSharingModel sharingModel = ProfitSharingModel.builder()
			.appid(userOauthList.get(0).getAppId())
			.transaction_id(settleOrderDTO.getPayBizNo())
			.out_order_no(settleOrderDTO.getSettleNo())
			.receivers(receiverModelList)
			.unfreeze_unsplit(false)
			.build();

		if(StringUtil.isBlank(wxPayApiConfig.getKeyPath())){
			return SettleOrderVO.builder().code(StringPool.NO).msg("未设置key.pem证书").build();
		}
		byte[] keyByte = Base64.getDecoder().decode(wxPayApiConfig.getKeyPath());
		InputStream keyInputStream = new ByteArrayInputStream(keyByte);
		PrivateKey privateKey = PayKit.getPrivateKeyByKeyContent(IoUtil.read(keyInputStream, StandardCharsets.UTF_8), AuthTypeEnum.RSA.getCode());
		IJPayHttpResponse response = WxPayApi.v3(
			RequestMethodEnum.POST,
			WxDomainEnum.CHINA.toString(),
			ProfitSharingApiEnum.PROFIT_SHARING_ORDERS.toString(),
			wxPayApiConfig.getMchId(),
			String.valueOf(wxPayApiConfig.getExParams()),
			null,
			privateKey,
			JSONUtil.toJsonStr(sharingModel)
		);
		if(response.getStatus() != 200){
			Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
			return SettleOrderVO.builder().code(StringPool.NO).msg(MapUtil.getStr(responseMap, "message")).build();
		}

		byte[] platformCertByte = Base64.getDecoder().decode(wxPayApiConfig.getPlatformCertPath());
		InputStream platformCert = new ByteArrayInputStream(platformCertByte);
		boolean verifySignature = WxPayKit.verifySignature(response, platformCert);
		if(!verifySignature){
			return SettleOrderVO.builder().code(StringPool.NO).msg("分账验签失败，请检查平台证书是否正确").build();
		}
		Map<String, Object> responseMap = JsonUtil.toMap(response.getBody());
		return SettleOrderVO.builder().code(StringPool.YES).msg(MapUtil.getStr(responseMap, "order_id")).build();
	}

}
